﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Reflection;
using System.Text;
using DBScript.Utils;
namespace DBScript
{
    /// <summary>
    /// Copyright (C) 2009-2012 Xuzhibin
    /// 数据访问基础类
    /// 用户可以修改满足自己项目的需要。
    /// Created On 2009-10-04 
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ProviderBase: IDBBase
    {
        //private string _connName = "";
        private List<string> _connNames;
        private bool _Distributed = false;
        private bool _RWSeparate = true;
        private bool _IsSwitch = false;
        private bool _isBeginTran = false;
        private string _QueryStr = "";
        private QueryBase _QueryBuilder = null;
        private List<DBParam> _Params = null;
        private DateTime _BeginTime;
        private bool _isDebug = false;
        private string _debugFilePath = "/log";

        private List<TransactionItem> _tranList = new List<TransactionItem>();
        private Dictionary<string, DBConfigNode> _dbConfigs;

        private string _curConnName = "";

        private string _LastInsert_ID_SQL = "";

        #region 构造函数
        /// <summary>
        /// 构造函数
        /// </summary>
        public ProviderBase()
        {
        }

        public ProviderBase(DBScriptConfig dsConfig)
        {
            bool distributed = false;
            if (dsConfig.DbConfigs.Count > 1)
            {
                distributed = true;
            }
            Init(dsConfig, distributed, true);
        }
        public ProviderBase(DBScriptConfig dsConfig, bool distributed, bool rw_separate)
        {
            Init(dsConfig, distributed, rw_separate);
        }

        private void Init(DBScriptConfig dsConfig, bool distributed, bool rw_separate)
        {
            _dbConfigs = dsConfig.DbConfigs;
            _connNames = new List<string>();
            foreach (string key in DBConfigs.Keys)
            {
                //_connName += key + ",";
                _connNames.Add(key);
            }
            //if (!string.IsNullOrEmpty(_connName))
            //{
            //    _connName = _connName.Substring(0, _connName.Length - 1);
            //}
            _Distributed = distributed;
            _RWSeparate = rw_separate;
            _isDebug = dsConfig.IsDebug;
            _debugFilePath = dsConfig.DebugFilePath;

            QueryBuilder = new MsSQLQuery();
            Params = new List<DBParam>();
        }
        #endregion

        #region 属性
        /// <summary>
        /// 数据库连接名数组
        /// </summary>
        public List<string> connNames
        {
            get
            {
                return _connNames;
            }
            set { _connNames = value; }
        }

        /// <summary>
        /// 数据库连接配置
        /// </summary>
        public Dictionary<string, DBConfigNode> DBConfigs
        {
            get
            {
                return _dbConfigs;
            }
            set
            {
                _dbConfigs = value;
            }
        }

        /// <summary>
        /// 是否分布式
        /// </summary>
        public bool Distributed
        {
            get { return _Distributed; }
            set { _Distributed = value; }
        }
        /// <summary>
        /// 是否读写分离
        /// </summary>
        public bool RWSeparate
        {
            get { return _RWSeparate; }
            set { _RWSeparate = value; }
        }
        /// <summary>
        /// 是否自定义切换数据库
        /// </summary>
        public bool IsSwitch
        {
            get { return _IsSwitch; }
            set { _IsSwitch = value; }
        }
        /// <summary>
        /// 是否开启事务
        /// </summary>
        public bool IsBeginTran
        {
            set
            {
                _isBeginTran = value;
            }
            get
            {
                return _isBeginTran;
            }
        }
        /// <summary>
        /// 最近的执行的Sql语句
        /// </summary>
        public string QueryStr
        {
            get{ return _QueryStr; }
            set { _QueryStr = value; }
        }
        /// <summary>
        /// 查询器
        /// </summary>
        public QueryBase QueryBuilder
        {
            get { return _QueryBuilder; }
            set { _QueryBuilder = value; }
        }
        /// <summary>
        /// 查询器
        /// </summary>
        public List<DBParam> Params
        {
            get { return _Params; }
            set { _Params = value; }
        }
        /// <summary>
        /// Sql语句开始执行时间
        /// </summary>
        public DateTime BeginTime
        {
            get { return _BeginTime; }
            set { _BeginTime = value; }
        }

        /// <summary>
        /// 当前数据库连接
        /// </summary>
        public string CurConnName
        {
            set { _curConnName = value; }
            get { return _curConnName; }
        }

        /// <summary>
        /// 是否调试
        /// </summary>
        public bool IsDebug
        {
            set
            {
                _isDebug = value;
            }
            get
            {
                return _isDebug;
            }
        }
        public string DebugFilePath
        {
            set
            {
                _debugFilePath = value;
            }
            get
            {
                return _debugFilePath;
            }
        }
        /// <summary>
        /// 获取最后插入的ID
        /// </summary>
        public string LastInsert_ID_SQL
        {
            set
            {
                _LastInsert_ID_SQL = value;
            }
            get
            {
                return _LastInsert_ID_SQL;
            }
        }

        public List<TransactionItem> TranList
        {
            set
            {
                _tranList = value;
            }
            get
            {
                return _tranList;
            }
        }
        #endregion 属性

        #region 数据库链接管理
        /// <summary>
        /// 根据数据库操作获取不同的数据库连接名
        /// </summary>
        /// <param name="sop"></param>
        /// <returns></returns>
        public string GetConnName(QueryType qty)
        {
            //string[] connNames = connName.Split(',');
            //非分布式，取第一个
            if (!Distributed)
            {
                CurConnName = connNames[0];
                return connNames[0];
            }
            Random random = new Random();
            int i = 0;
            if (RWSeparate && qty == QueryType.Read)
            {
                //读写分离，第一个为写
                i = random.Next(1, connNames.Count);
            }
            else if (!RWSeparate && qty == QueryType.Read)
            {
                //非读写分离，随机取一个
                i = random.Next(0, connNames.Count);
            }
            //Console.WriteLine(qty.ToString()+":"+i);
            CurConnName = connNames[i];
            return connNames[i];
        }

        public DBConfigNode GetDBConfig(QueryType qty)
        {
            string name = GetConnName(qty);
            return DBConfigs[name];
        }

        /// <summary>
        /// 自定义切换数据库
        /// </summary>
        /// <param name="CName"></param>
        /// <returns></returns>
        public virtual bool SwitchConnect(string CName)
        {
            CurConnName = CName;
            IsSwitch = true;
            return true;
        }
        /// <summary>
        /// 停止切换，还原为默认方式
        /// </summary>
        /// <returns></returns>
        public bool SwitchEnd()
        {
            IsSwitch = false;
            return true;
        }
        #endregion 数据库链接管理

        #region Add

        /// <summary>
        /// 添加记录，返回当前插入的这条记录的ID
        /// </summary>
        /// <param name="model">实体层某实体的实例</param>
        public virtual int Add<T>(T model) where T : DBModel, new()
        {
            T t = new T();
            StringBuilder strSql = new StringBuilder();
            StringBuilder strParameter = new StringBuilder();
            strSql.Append(string.Format("insert into {0} (", t.TableName));
            PropertyInfo[] pis = GetPropertyInfos<T>();
            //PropertyInfo keyProperty = new PropertyInfo();

            List<DBParam> listParam = new List<DBParam>();
            for (int i = 0; i < pis.Length; i++)
            {
                DbColumnAttribute dbColumn = GetDBColumn(pis[i]);
                if (dbColumn==null)
                {
                    continue;
                }

                if (t.PrimaryKey == dbColumn.Name || dbColumn.IsDbGenerate)
                    continue;

                strSql.Append(dbColumn.Name + ","); //构造SQL语句前半部份 
                strParameter.Append("@" + dbColumn.Name + ","); //构造参数SQL语句
                listParam.Add(new DBParam
                {
                    ParameterName = dbColumn.Name,
                    DbType = TypeConvert.GetDbType(pis[i].PropertyType),
                    Value = pis[i].GetValue(model, null)
                });
            }
            strSql = strSql.Replace(",", ")", strSql.Length - 1, 1);
            strParameter = strParameter.Replace(",", ")", strParameter.Length - 1, 1);
            strSql.Append(" values (");
            strSql.Append(strParameter + ";");


            strSql.Append(string.Format(LastInsert_ID_SQL, t.TableName));


            object obj = From<T>().SetSQL(strSql.ToString()).SetListParams(listParam).ExecuteScalar(QueryType.Create);

            return TypeConvert.ToInt32(obj);
        }

        #endregion Add

        #region Delete
        /// <summary>
        /// 删除记录
        /// </summary>
        /// <param name="id">记录ID</param>
        public int Delete<T>(int id) where T : DBModel, new()
        {
            T t = new T();
            QueryBuilder.Table = t.TableName;
            return Where(string.Format("{0}={1}",t.PrimaryKey, id)).Delete();
        }

        public int Delete<T>(long id) where T : DBModel, new()
        {
            T t = new T();
            QueryBuilder.Table = t.TableName;
            return Where(string.Format("{0}={1}", t.PrimaryKey, id)).Delete();
        }

        /// <summary>
        /// 删除记录
        /// </summary>
        /// <param name="strWhere">Where子句</param>
        public virtual int Delete()
        {
            return SetSQL(QueryBuilder.ExportDelete()).ExecuteNonQuery(QueryType.Delete);
        }

        public int Delete<T>() where T : DBModel, new()
        {
            T t = new T();
            if (string.IsNullOrEmpty(QueryBuilder.Table))
            {
                QueryBuilder.Table = t.TableName;
            }
            return Delete();
        }
        #endregion Delete     

        #region Update

        /// <summary>
        /// 更新记录
        /// </summary>
        /// <param name="model">需要更新到数据库的实体类</param> 
        public virtual bool Update<T>(T model) where T : DBModel, new()
        {
            T t = new T();
            StringBuilder strSql = new StringBuilder();
            strSql.Append("update  " + t.TableName + " set ");
            PropertyInfo[] pis = GetPropertyInfos<T>();

            List<DBParam> listParam = new List<DBParam>();
            for (int i = 0; i < pis.Length; i++)
            {
                DbColumnAttribute dbColumn = GetDBColumn(pis[i]);
                if (dbColumn==null)
                {
                    continue;
                }

                if (dbColumn.Name != t.PrimaryKey)
                {
                    strSql.Append(dbColumn.Name + "=" + "@" + dbColumn.Name + ",");
                }
                listParam.Add(new DBParam
                {
                    DbType = TypeConvert.GetDbType(pis[i].PropertyType),
                    ParameterName = dbColumn.Name,
                    Value = pis[i].GetValue(model, null)
                });
            }
            strSql = strSql.Replace(",", " ", strSql.Length - 1, 1);
            strSql.Append(" where " + t.PrimaryKey + "=@" + t.PrimaryKey);

            bool re = From<T>().SetSQL(strSql.ToString()).SetListParams(listParam).ExecuteNonQuery(QueryType.Update) > 0 ? true : false;
            return re;
        }
        /// <summary>
        /// 更新记录
        /// </summary>
        /// <param name="field">更新字段</param>
        /// <returns></returns>
        public virtual IDBBase UpdateFields(string fields)
        {
            QueryBuilder.UpdateFields = fields;
            return this;
        }
        /// <summary>
        /// 更新记录
        /// </summary>
        /// <returns></returns>
        public virtual bool Update()
        {

            bool re = SetSQL(QueryBuilder.ExportUpdateFields()).ExecuteNonQuery(QueryType.Update) > 0 ? true : false;
            return re;
        }
        #endregion Update

        #region Select
        /// <summary>
        /// 设置Table
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public virtual IDBBase From<T>() where T : DBModel, new()
        {
            T t=new T();
            QueryBuilder.Table = t.TableName;
            QueryBuilder.PrimaryKey = t.PrimaryKey;
            return this;
        }
        public virtual IDBBase From(string table, string pkey)
        {
            QueryBuilder.Table = table;
            QueryBuilder.PrimaryKey = pkey;
            return this;
        }

        /// <summary>
        /// 设置SQL
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public virtual IDBBase SetSQL(string sql)
        {
            QueryBuilder.Sql = sql;
            return this;
        }

        /// <summary>
        /// 设置Query
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public virtual IDBBase SetQuery(QueryBase query)
        {
            QueryBuilder = query;
            return this;
        }

        /// <summary>
        /// 设置条件
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        public virtual IDBBase Where(string where)
        {
            QueryBuilder.Where = where;
            return this;
        }

        /// <summary>
        /// 查询字段
        /// </summary>
        /// <param name="columns"></param>
        /// <returns></returns>
        public virtual IDBBase Select(string columns)
        {
            QueryBuilder.Columns = columns;
            return this;
        }

        /// <summary>
        /// 排序
        /// </summary>
        /// <param name="orderby"></param>
        /// <returns></returns>
        public virtual IDBBase OrderBy(string orderby)
        {
            QueryBuilder.OrderBy = orderby;
            return this;
        }

        /// <summary>
        /// 分组
        /// </summary>
        /// <param name="groupby"></param>
        /// <returns></returns>
        public virtual IDBBase GroupBy(string groupby)
        {
            QueryBuilder.GroupBy = groupby;
            return this;
        }

        /// <summary>
        /// 分组后查询条件
        /// </summary>
        /// <param name="having"></param>
        /// <returns></returns>
        public virtual IDBBase Having(string having)
        {
            QueryBuilder.Having = having;
            return this;
        }

        /// <summary>
        /// 分页
        /// </summary>
        public virtual IDBBase Page(int index, int size)
        {
            int first=(index-1)*size;
            int lengh=size;
            return LimitFirst(first).LimitLengh(lengh) ;
        }
        public virtual IDBBase LimitFirst(int first)
        {
            QueryBuilder.LimitFirst = first;
            return this;
        }
        public virtual IDBBase LimitLengh(int lengh)
        {
            QueryBuilder.LimitLengh = lengh;
            return this;
        }

        #endregion Select

        #region 设置参数
        public virtual IDBBase SetString(string name, string value)
        {
            Params.Add(new DBParam() { DbType = DbType.String, ParameterName = name, Value = value });
            return this;
        }
        public virtual IDBBase SetInt(string name, int value)
        {
            Params.Add(new DBParam() { DbType = DbType.Int32, ParameterName = name, Value = value });
            return this;
        }
        public virtual IDBBase SetParam(DBParam pm)
        {
            Params.Add(pm);
            return this;
        }
        public virtual IDBBase SetListParams(List<DBParam> listPm)
        {
            Params.AddRange(listPm);
            return this;
        }
        #endregion 设置参数

        #region 返回单个值
        /// <summary>
        /// 最大ID值
        /// </summary>
        public virtual int MaxInt(string key)
        {
            return Select(string.Format("max({0})", key)).GetInt();
        }
        /// <summary>
        /// 获得记录数
        /// </summary>
        public virtual int GetCount()
        {
            return Select("count(*) as ct").GetInt();
        }
        /// <summary>
        /// 获取Int
        /// </summary>
        /// <returns></returns>
        public virtual int GetInt()
        {
            object obj = ExecuteScalar(QueryType.Read);
            return obj == null ? 0 : Convert.ToInt32(obj);
        }

        /// <summary>
        /// 获取String
        /// </summary>
        /// <returns></returns>
        public virtual string GetString()
        {
            object obj = ExecuteScalar(QueryType.Read);
            return obj == null ? "" : (String)obj;
        }

        /// <summary>
        /// 获取object[]列表
        /// </summary>
        /// <returns></returns>
        public virtual List<object[]> GetListObjects()
        {
            List<object[]> listObjs=null;
            using (IDataReader dr = GetReader())
            {
                while (dr.Read())
                {
                    if(listObjs==null)
                    {
                        listObjs=new List<object[]>();
                    }
                    List<object> objs=new List<object>();

                    for(int i=0;i<dr.FieldCount;i++)
                    {
                        objs.Add(dr.GetValue(i));
                    }
                    listObjs.Add(objs.ToArray());
                }
            }
            return listObjs;
        }
        #endregion 返回单个值

        #region Exists
        /// <summary>
        /// 判断记录是否存在
        /// </summary>
        /// <param name="id">记录ID</param>
        public virtual bool Exists(int id)
        {
            return Where(string.Format("{0}=@{0}", QueryBuilder.PrimaryKey))
                   .SetInt(QueryBuilder.PrimaryKey, id).Exists();
        }

        public virtual bool Exists(long id)
        {
            return Where(string.Format("{0}=@{0}", QueryBuilder.PrimaryKey))
                   .SetParam(new DBParam { ParameterName = QueryBuilder.PrimaryKey, DbType = DbType.Int64, Value = id }).Exists();
        }

        /// <summary>
        /// 判断记录是否存在
        /// </summary>
        public virtual bool Exists()
        {
            object obj = SetSQL(QueryBuilder.ExportExists()).ExecuteScalar(QueryType.Read);
            int cmdresult;
            if ((Equals(obj, null)) || (Equals(obj, DBNull.Value)))
            {
                cmdresult = 0;
            }
            else
            {
                cmdresult = int.Parse(obj.ToString());
            }
            if (cmdresult == 0)
            {
                return false;
            }
            return true;
        }
        #endregion Exists

        #region GetModel

        /// <summary>
        /// 获得一个Model对象实例
        /// </summary>
        /// <param name="id">主键ID的值</param>
        public virtual T GetModel<T>(int id) where T : DBModel, new()
        {
            T t = new T();
            return Where(string.Format("{0}=@{0}", t.PrimaryKey))
                   .SetInt(t.PrimaryKey, id).GetModel<T>();
        }

        public virtual T GetModel<T>(long id) where T : DBModel, new()
        {
            T t = new T();
            return Where(string.Format("{0}=@{0}", t.PrimaryKey))
                   .SetParam(new DBParam { ParameterName = t.PrimaryKey, DbType = DbType.Int64, Value = id }).GetModel<T>();
        }

        /// <summary>
        /// 获得一个Model对象实例
        /// </summary>
        public virtual T GetModel<T>() where T : DBModel, new()
        {
            T model = new T();
            if (string.IsNullOrEmpty(QueryBuilder.Table))
            {
                QueryBuilder.Table = model.TableName;
            }
            using (IDataReader dr = SetSQL(QueryBuilder.ExportModel()).GetReader())
            {
                if (dr != null)//判断dr是否为null
                {
                    if (dr.Read())
                    {
                        model = GetModel<T>(dr);
                    }
                    else
                    {
                        return null;
                    }
                }
               
            }
            return model;
        }

        /// <summary>
        /// 获得一个Model对象实例
        /// </summary>
        public virtual T GetModel<T>(IDataReader dr) where T : DBModel, new()
        {
            T model = new T();
            PropertyInfo[] pis = GetPropertyInfos<T>();
            int iIndex;
            foreach (PropertyInfo pi in pis)
            {
                DbColumnAttribute dbColumn = GetDBColumn(pi);
                if (dbColumn==null)
                {
                    continue;
                }

                try
                {
                    iIndex = dr.GetOrdinal(dbColumn.Name);
                }
                catch (IndexOutOfRangeException)
                {
                    continue;
                }
                try
                {
                    if (dr.IsDBNull(iIndex))
                    {
                        continue;
                    }
                }
                catch
                {
                    continue;
                }
                //Console.WriteLine(pi.Name + ":" + dr.GetValue(iIndex).GetType());
                pi.SetValue(model, ConvertValue(dr.GetValue(iIndex)), null);
            }
            //dr.Dispose();
            return model;
        }
        /// <summary>
        /// 获得一个Model对象实例
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dataRow"></param>
        /// <returns></returns>
        public virtual T GetModel<T>(DataRow dataRow) where T : DBModel, new()
        {
            //Type t = typeof(T);
            PropertyInfo[] properties = GetPropertyInfos<T>();

            T obj = new T();
            if (dataRow==null)
            {
                return default(T);
            }
            foreach (PropertyInfo pi in properties)
            {
                DbColumnAttribute dbColumn = GetDBColumn(pi);
                if (dbColumn==null)
                {
                    continue;
                }

                if (dataRow.Table.Columns.Contains(dbColumn.Name))
                {
                    try
                    {

                        pi.SetValue(obj, Convert.ChangeType(dataRow[dbColumn.Name], pi.PropertyType), null);
                    }
                    catch
                    {
                    }
                }
            }
            return obj;
        }
        #endregion GetModel

        #region  GetList

        /// <summary>
        /// 获得数据集
        /// </summary>
        /// <returns></returns>
        public virtual List<T> GetList<T>() where T : DBModel, new()
        {
            T t = new T();
            if (string.IsNullOrEmpty(QueryBuilder.Table))
            {
                QueryBuilder.Table = t.TableName;
                QueryBuilder.PrimaryKey = t.PrimaryKey;
            }
            return GetList<T>(GetReader());
        }

        /// <summary>
        /// 获取数据集及总数
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public virtual ArrayList GetListAndCount<T>() where T : DBModel, new()
        {
            QueryBase tempQueryBuilder = QueryBuilder;
            List<DBParam> tempParams = Params;
            List<T> dataList = this.GetList<T>();
            int dataCount = this.SetQuery(tempQueryBuilder).SetListParams(tempParams).GetCount();
            ArrayList returnValue = new ArrayList();
            returnValue.Add(dataList);
            returnValue.Add(dataCount);
            return returnValue;
        }

        /// <summary>
        /// 获得List集合
        /// </summary>
        /// <param name="dr">将DataReader里的实体转到List</param>
        public virtual List<T> GetList<T>(IDataReader dr) where T : DBModel, new()
        {
            List<T> list = new List<T>();
            if (dr == null)
            {
                return list;
            }
            while (dr.Read())
            {
                list.Add(GetModel<T>(dr));
            }
            dr.Dispose();
            return list;
        }
        /// <summary>
        /// 获得List集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dt"></param>
        /// <returns></returns>
        public virtual List<T> GetList<T>(DataTable dt) where T : DBModel, new()
        {
            List<T> ls = new List<T>();
            foreach (DataRow row in dt.Rows)
            {
                ls.Add(GetModel<T>(row));
            }
            return ls;
        }
        #endregion  GetList        

        #region  GetReader

        /// <summary>
        /// 获得数据集
        /// </summary>
        /// <returns></returns>
        public virtual IDataReader GetReader()
        {
            return null;
        }

        public virtual IDataReader GetReader<T>() where T : DBModel, new()
        {
            T t = new T();
            if (string.IsNullOrEmpty(QueryBuilder.Table))
            {
                QueryBuilder.Table = t.TableName;
                QueryBuilder.PrimaryKey = t.PrimaryKey;
            }
            return GetReader();
        }

        #endregion  GetReader        

        #region 事务

        /// <summary>
        /// 开启事务
        /// </summary>
        public virtual void BeginTransaction()
        {
            IsBeginTran = true;
        }

        /// <summary>
        /// 提交事务
        /// </summary>
        public virtual void Commit()
        {
            ExecuteSqlTran(TranList);
            IsBeginTran = false;
            TranList = new List<TransactionItem>();
            ReSet();
        }

        #endregion 事务

        #region 执行SQL语句

        /// <summary>
        /// 执行sql语句并返回单个结果
        /// </summary>
        public virtual object ExecuteScalar()
        {
            return ExecuteScalar(QueryType.Other);
        }
        public virtual object ExecuteScalar(QueryType qty)
        {
            return null;
        }
        /// <summary>
        /// 执行sql语句，返回受影响行数
        /// </summary>
        public virtual int ExecuteNonQuery()
        {
            return ExecuteNonQuery(QueryType.Other);
        }
        public virtual int ExecuteNonQuery(QueryType qty)
        {
            return 0;
        }
        /// <summary>
        /// 执行多条SQL语句，实现数据库事务，返回受影响行数。
        /// </summary>
        /// <param name="SQLStringList"></param>
        public virtual int ExecuteSqlTran(List<TransactionItem> tranList)
        {
            return 0;
        }
        #endregion 

        #region 辅助函数
        /// <summary>
        /// 获取类型属性集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        protected virtual PropertyInfo[] GetPropertyInfos<T>() where T : DBModel, new()
        {
            Type type=typeof(T);
            string key=string.Format("Class.PropertyInfos.{0}",type.FullName);
            StaticHashCache cache=new StaticHashCache();
            PropertyInfo[] pis = cache[key] as PropertyInfo[];

            if (pis == null)
            {
                pis = type.GetProperties(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public);
            }

            cache[key] = pis;
            return pis;
        }
        /// <summary>
        /// 转换值
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        protected virtual object ConvertValue(object obj)
        {
            return obj;
        }
        /// <summary>
        /// 重置
        /// </summary>
        protected virtual void ReSet()
        {
            QueryBuilder = null;
            Params = new List<DBParam>();
            QueryStr = "";
        }

        /// <summary>
        /// 根据实体属性获取数据库字段
        /// </summary>
        /// <param name="pi"></param>
        /// <returns></returns>
        protected virtual DbColumnAttribute GetDBColumn(PropertyInfo pi)
        {
            DbColumnAttribute returnValue = new DbColumnAttribute();
            object[] attrs = pi.GetCustomAttributes(typeof(ExcludeAttribute), false);
            if (attrs.Length > 0)
            {
                return null;
            }
            attrs = pi.GetCustomAttributes(typeof(DbColumnAttribute), false);
            if (attrs.Length > 0)
            {
                returnValue = attrs[0] as DbColumnAttribute;
            }
            if (string.IsNullOrEmpty(returnValue.Name))
            {
                returnValue.Name = pi.Name;
            }

            return returnValue;
        }
        #endregion 辅助函数

        #region 日志函数
        /// <summary>
        /// 参数调试
        /// </summary>
        /// <param name="lsParams"></param>
        /// <returns></returns>
        protected string ParamsDebug(List<DBParam> lsParams)
        {
            StringBuilder sb = new StringBuilder();
            foreach(DBParam param in lsParams)
            {
                sb.AppendLine(string.Format("@{0}={1}",param.ParameterName,param.Value));
            }
            return sb.ToString();
        }
        /// <summary>
        /// 调试SQL
        /// </summary>
        /// <param name="content"></param>
        protected void SqlDebug(string content)
        {
            if (IsDebug)
            {
                LibHelper.WriteLog(string.Format("{0}/sqllog.{1}.log",DebugFilePath,DateTime.Now.ToString("yy-MM-dd")),content);
            }
        }
        /// <summary>
        /// Sql操作共运行时间
        /// </summary>
        /// <returns></returns>
        protected double RunTime()
        {
           TimeSpan ts = DateTime.Now.Subtract(this.BeginTime);
           return ts.Ticks/10000;
        }
        #endregion 日志函数
    }
}
